package com.xjrsoft.module.workflow.listener;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xjrsoft.core.secure.utils.SecureUtil;
import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.FlowableUtil;
import com.xjrsoft.core.tool.utils.SpringUtil;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.base.service.IXjrBaseTempfieldService;
import com.xjrsoft.module.workflow.entity.XjrNwfScheme;
import com.xjrsoft.module.workflow.service.IXjrNwfSchemeService;
import lombok.SneakyThrows;
import org.flowable.bpmn.model.Activity;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.engine.HistoryService;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;

import java.util.ArrayList;
import java.util.List;


//流程结束监听
public class EndExecutionListener implements ExecutionListener {

    @SneakyThrows
    @Override
    public void notify(DelegateExecution delegateExecution) {
        IXjrNwfSchemeService nwfSchemeService = SpringUtil.getBean(IXjrNwfSchemeService.class);
        RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class);
        RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
        HistoryService historyService = SpringUtil.getBean(HistoryService.class);
        IdentityService identityService = SpringUtil.getBean(IdentityService.class);
        String rootProcessInstanceId = delegateExecution.getRootProcessInstanceId();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(rootProcessInstanceId).singleResult();
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(rootProcessInstanceId).list();
        ExecutionEntityImpl execution = (ExecutionEntityImpl) delegateExecution;
        ExecutionEntityImpl superExecution = execution.getSuperExecution();
        if (superExecution != null && StringUtil.isNotBlank(rootProcessInstanceId)) {
            // 通过人数
            Object completeCount = runtimeService.getVariable(rootProcessInstanceId, "completeCount");
            if (completeCount != null) {
                runtimeService.setVariable(rootProcessInstanceId, "completeCount", Long.valueOf(String.valueOf(completeCount)) + 1);
            }
        }
        for (HistoricActivityInstance historicActivityInstance : list) {
            String calledProcessInstanceId = historicActivityInstance.getCalledProcessInstanceId();
            if (StringUtil.equals(calledProcessInstanceId, delegateExecution.getProcessInstanceId())) {
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
                // 设置当前操作人，对于调用活动可以获取到当前操作人
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(rootProcessInstanceId).singleResult();
                String nwfSchemeInfoId = processDefinition.getDescription();
                XjrNwfScheme xjrNwfScheme = nwfSchemeService.getBySchemeInfoId(nwfSchemeInfoId);
                String json = xjrNwfScheme.getFjson();
                List<FlowElement> node = FlowableUtil.getCallActivityNode(historicActivityInstance.getActivityId(), processDefinition.getId(), 1, new ArrayList<String>());
                if (CollectionUtil.isNotEmpty(node)) {
                    for (FlowElement flowElement : node) {
                        if (flowElement instanceof Activity) {
                            String activityId = flowElement.getId();
                            //获取子流程开始节点发起人
                            JSONObject jsonObject = JSONObject.parseObject(json);
                            JSONArray childShapes = jsonObject.getJSONArray("childShapes");
                            for (int i = 0; i < childShapes.size(); i++) {
                                JSONObject childShape = childShapes.getJSONObject(i);
                                String resourceId = childShape.getString("resourceId");
                                if (StringUtil.equals(resourceId, activityId)) {
                                    String subProcessInitiator = childShape.getJSONObject("properties").getString("subProcessInitiator");
                                    List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(rootProcessInstanceId).activityId(subProcessInitiator).list();
                                    String assignee = "";
                                    if (CollectionUtil.isNotEmpty(historicActivityInstanceList)) {
                                        HistoricActivityInstance historicActivityInstance1 = historicActivityInstanceList.get(0);
                                        assignee = historicActivityInstance1.getAssignee();
                                        if (StringUtil.equals(historicActivityInstance1.getActivityType(), "startEvent")) {
                                            assignee = processInstance.getStartUserId();
                                        }
                                    }
                                    if (StringUtil.isBlank(assignee)) {
                                        assignee = SecureUtil.getUserId();
                                    }
                                    // 设置流程发起人
                                    identityService.setAuthenticatedUserId(assignee);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
